﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ICUP13.Management
{
    public static class StateMachine
    {
        // Data Members
        private static IBaseState CurrentState = null;
        private static Stack<IBaseState> StateStack = new Stack<IBaseState>();
        private static IBaseState _ChangeStateQueue = null;
        private static IBaseState _AddStateQueue = null;
        private static bool _GoBackQueue = false;
        private static bool _EmptyQueue = true;

        public static void Initalize()
        {
        }
        //Call ChangeStateQueue Instead
        //Does not add old state to the stack
        private static void ChangeState(IBaseState NewState)
        {
            if (CurrentState != null)
                CurrentState.Exit();
            CurrentState = NewState;
            if (CurrentState != null)
                CurrentState.Enter();
        }

        //Call AddStateQueue Instead
        //Add old state to the stack and changes the current state
        private static void AddState(IBaseState NewState)
        {
            if (CurrentState != null)
                StateStack.Push(CurrentState);
            CurrentState = NewState;
            if (CurrentState != null)
                CurrentState.Enter();
        }

        //Call BackStateQueue Instead
        //Exit the current state, then set the 
        //current state to the last state on the stack
        private static void BackState()
        {
            if (CurrentState != null)
                CurrentState.Exit();
            if (StateStack.Count > 0)
                CurrentState = StateStack.Pop();
            else
                CurrentState = null;
        }

        public static bool StateInput(float Delta, float TotalElapsed, int FPS)
        {
            if (CurrentState != null)
                return CurrentState.Input(Delta, TotalElapsed, FPS);
            return false;
        }
        public static void StateUpdate(float Delta, float TotalElapsed, int FPS)
        {
            if (CurrentState != null)
                CurrentState.Update(Delta, TotalElapsed, FPS);
        }
        public static void StateDraw(float Delta, float TotalElapsed, int FPS)
        {
            if (CurrentState != null)
                CurrentState.Draw(Delta, TotalElapsed, FPS);
        }
        public static void AddStateQueue(IBaseState NewStateQueue)
        {
            _AddStateQueue = NewStateQueue;
            _EmptyQueue = false;
        }
        public static void ChangeStateQueue(IBaseState NewStateQueue)
        {
            _ChangeStateQueue = NewStateQueue;
            _EmptyQueue = false;
        }
        public static void BackStateQueue()
        {
            _GoBackQueue = true;
            _EmptyQueue = false;
        }
        public static void CheckQueue()
        {
            if (_EmptyQueue)
                return;
            _EmptyQueue = false;

            if (_AddStateQueue != null)
            {
                AddState(_AddStateQueue);
                _AddStateQueue = null;
            }
            if (_ChangeStateQueue != null)
            {
                ChangeState(_ChangeStateQueue);
                _ChangeStateQueue = null;
            }
            if (_GoBackQueue == true)
            {
                BackState();
                _GoBackQueue = false;
            }
        }
        public static void ClearStateMachine()
        {
            if (CurrentState != null)
                CurrentState.Exit();
            while (StateStack.Count > 0)
                StateStack.Pop().Exit();
            CurrentState = null;
        }
    }
}
